//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.tl.satoken.listener;

import com.tl.satoken.domain.entity.Player;
import com.tl.satoken.service.RoomService;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.messaging.SessionConnectedEvent;
import org.springframework.web.socket.messaging.SessionDisconnectEvent;
import org.springframework.web.socket.messaging.SessionSubscribeEvent;
import org.springframework.web.socket.messaging.SessionUnsubscribeEvent;

@Component
public class WebSocketEventListener {
    private static final Logger log = LoggerFactory.getLogger(WebSocketEventListener.class);
    @Autowired
    private SimpMessagingTemplate messagingTemplate;
    @Autowired
    private RoomService roomService;
    private final Map<String, Player> sessionPlayerMap = new ConcurrentHashMap();
    private final Map<String, Long> playerLastHeartbeat = new ConcurrentHashMap();

    public WebSocketEventListener() {
    }

    @EventListener
    public void handleSessionConnected(SessionConnectedEvent event) {
        StompHeaderAccessor sha = StompHeaderAccessor.wrap(event.getMessage());
        String sessionId = sha.getSessionId();
        log.info("WebSocket连接建立，会话ID: {}", sessionId);
    }

    @EventListener
    public void handleSessionDisconnect(SessionDisconnectEvent event) {
        StompHeaderAccessor sha = StompHeaderAccessor.wrap(event.getMessage());
        String sessionId = sha.getSessionId();
        log.info("WebSocket连接断开，会话ID: {}", sessionId);
        this.handlePlayerDisconnect(sessionId);
    }

    @EventListener
    public void handleSessionSubscribe(SessionSubscribeEvent event) {
        StompHeaderAccessor sha = StompHeaderAccessor.wrap(event.getMessage());
        String sessionId = sha.getSessionId();
        String destination = sha.getDestination();
        log.info("用户订阅主题，会话ID: {}, 主题: {}", sessionId, destination);
    }

    @EventListener
    public void handleSessionUnsubscribe(SessionUnsubscribeEvent event) {
        StompHeaderAccessor sha = StompHeaderAccessor.wrap(event.getMessage());
        String sessionId = sha.getSessionId();
        log.info("用户取消订阅，会话ID: {}", sessionId);
    }

    private void handlePlayerDisconnect(String sessionId) {
        Player player = (Player)this.sessionPlayerMap.remove(sessionId);
        if (player != null) {
            this.playerLastHeartbeat.remove(player.getId());
            log.info("检测到玩家 {} 断开连接，从房间中移除", player.getUsername());
            if (this.roomService.leaveRoom(player.getId())) {
                String roomId = player.getRoomId();
                List<Player> remainingPlayers = this.roomService.getPlayersInRoom(roomId);
                this.messagingTemplate.convertAndSend("/topic/room/" + roomId, remainingPlayers);
                log.info("房间 {} 剩余玩家数量: {}", roomId, remainingPlayers.size());
            }
        }

    }

    public void addSessionPlayer(String sessionId, Player player) {
        this.sessionPlayerMap.put(sessionId, player);
        this.playerLastHeartbeat.put(player.getId(), System.currentTimeMillis());
    }

    public void removeSessionPlayer(String sessionId) {
        Player player = (Player)this.sessionPlayerMap.remove(sessionId);
        if (player != null) {
            this.playerLastHeartbeat.remove(player.getId());
        }

    }

    public void updatePlayerHeartbeat(String playerId) {
        this.playerLastHeartbeat.put(playerId, System.currentTimeMillis());
    }

    public Map<String, Player> getSessionPlayerMap() {
        return this.sessionPlayerMap;
    }

    public Map<String, Long> getPlayerLastHeartbeat() {
        return this.playerLastHeartbeat;
    }
}
